package com.zyl.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Random;

/**
 * 订单服务切面类：实现5种AOP增强需求
 * 1. @Aspect：声明此类是切面类（含增强逻辑）
 * 2. @Component：将切面类注入IOC容器（Spring才能管理并织入）
 */
@Aspect
@Component
public class OrderAspect {


    @Pointcut("execution(* com.zyl.service.OrderService.*(..))")
    public void orderAllMethods() {} // 切入点方法：无逻辑，仅作为标识

    @Pointcut("execution(* com.zyl.service.OrderService.add(..)) || execution(* com.zyl.service.OrderService.delete(..))")
    public void orderAddDeleteMethods() {} // 切入点方法：标识add和delete



    @Before(value = "orderAllMethods()")
    public void beforeAdvice(JoinPoint joinPoint) {
        // JoinPoint：获取目标方法信息（如方法名、参数，可选）
        String methodName = joinPoint.getSignature().getName(); // 获取当前执行的方法名
        System.out.println("[前置增强] hello, 我是一个前置增强 | 目标方法：" + methodName);
    }



    @After(value = "orderAddDeleteMethods()")
    public void afterAdvice(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("[后置增强] bye, 我是一个后置增强 | 目标方法：" + methodName);
        System.out.println("----------------------------------------");
    }



    @AfterReturning(value = "orderAllMethods()", returning = "result")
    public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
        String methodName = joinPoint.getSignature().getName();
        // 区分void和非void方法的返回值
        String returnMsg = (result == null) ? "无返回值（void方法）" : "返回值：" + result;
        System.out.println("[返回值增强] 目标方法：" + methodName + " | " + returnMsg);
    }



    @Around(value = "orderAllMethods()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        // 1. 方法执行前：记录开始时间（毫秒级）
        long startTime = System.currentTimeMillis();

        // 2. 执行目标方法（核心！必须调用，否则目标方法不会执行）
        Object result = joinPoint.proceed(); // 调用目标方法，获取返回值

        // 3. 方法执行后：计算执行时间
        long endTime = System.currentTimeMillis();
        long costTime = endTime - startTime;
        String methodName = joinPoint.getSignature().getName();
        System.out.println("[环绕增强-计时] 目标方法：" + methodName + " | 执行时间：" + costTime + " 毫秒");


        return result;
    }




    @Before(value = "orderAddDeleteMethods()")
    public void permissionCheckAdvice(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        // 模拟权限校验：生成0或1的随机数
        int permission = new Random().nextInt(2); // 0或1

        // 判断权限
        if (permission == 1) {
            // 无权限：抛异常终止目标方法执行（后续增强和业务逻辑都不会执行）
            throw new RuntimeException("[权限校验增强] 目标方法：" + methodName + " | 权限不足！无法执行操作");
        } else {
            System.out.println("[权限校验增强] 目标方法：" + methodName + " | 权限通过，允许执行");
        }
    }
}